#include "main.h"
#include "usart.h"
#include "string.h"
#include "usbd_cdc_if.h"


#define SEND_BUF_NUM	5
#define SEND_BUF_SIZE	128
#define RECV_BUF_NUM	5
#define RECV_BUF_SIZE	128		


static uint8_t 	cdc_send_buf[SEND_BUF_NUM][SEND_BUF_SIZE];
static uint16_t	cdc_send_len[SEND_BUF_NUM]={0};
static uint8_t 	cdc_recv_buf[RECV_BUF_NUM][RECV_BUF_SIZE];
static uint16_t	cdc_recv_len[RECV_BUF_NUM]={0};

UART_HandleTypeDef *cdcuart;

void cuart_init(UART_HandleTypeDef *uartHandle)
{
	cdcuart=uartHandle;
	__HAL_UART_ENABLE_IT(cdcuart,UART_IT_RXNE);
	__HAL_UART_ENABLE_IT(cdcuart,UART_IT_IDLE);

} 

void cuart_config(uint32_t baud,uint8_t stop,uint8_t parity)
{
  cdcuart->Init.BaudRate = baud;
  cdcuart->Init.WordLength = UART_WORDLENGTH_8B;
	switch(stop)
	{
		case 0:
			cdcuart->Init.StopBits = UART_STOPBITS_1;
			break;
		case 1:
			cdcuart->Init.StopBits = UART_STOPBITS_1_5;
			break;
		case 2:
			cdcuart->Init.StopBits = UART_STOPBITS_2;
			break;
	}
	switch(parity)
	{
		case 0:
			cdcuart->Init.Parity = UART_PARITY_NONE;
			break;
		case 1:
			cdcuart->Init.Parity = UART_PARITY_ODD;
			break;
		case 2:
			cdcuart->Init.Parity = UART_PARITY_EVEN;
			break;
	}	
  cdcuart->Init.Parity = UART_PARITY_NONE;
  cdcuart->Init.Mode = UART_MODE_TX_RX;
  cdcuart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
  cdcuart->Init.OverSampling = UART_OVERSAMPLING_16;
  cdcuart->Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  cdcuart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(cdcuart) != HAL_OK)
  {
    Error_Handler();
  }
}

#if 0
uint32_t cuart_send_store(uint8_t *buf,uint16_t len)
{
	uint32_t tlen=len;
	if(app_fifo_write(&cdc.send_fifo,buf,&tlen))return tlen;
	return 0;
}

void cuart_send()
{
	cdc.send_size=SEND_BUF_SIZE;
	if(app_fifo_read(&cdc.send_fifo,cdc.send_buf,&cdc.send_size))
	{
		HAL_UART_Transmit_IT(&huart1,cdc.send_buf,cdc.send_size);
	}
}
#endif

uint32_t cuart_send_store(uint8_t *buf,uint16_t len)
{
	uint16_t tlen=len;
	for(uint8_t i=0;i<SEND_BUF_NUM;i++)
	{
		if(cdc_send_len[i]==0)
		{
			if(tlen>SEND_BUF_SIZE)tlen=SEND_BUF_SIZE;
			memcpy(cdc_send_buf[i],buf,tlen);
			cdc_send_len[i]=tlen;
			return tlen;
		}
	}
	return 0;	
}

uint32_t cuart_send()
{
	uint16_t tlen=0;
	for(uint8_t i=0;i<SEND_BUF_NUM;i++)
	{
		if(cdc_send_len[i]!=0)
		{
			HAL_UART_Transmit(cdcuart,cdc_send_buf[i],cdc_send_len[i],100);
			tlen=cdc_send_len[i];
			cdc_send_len[i]=0;
			HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
			return tlen;
		}	
	}
	return tlen;
}

uint8_t cuart_recv_store(uint8_t *buf,uint16_t len)
{
	uint16_t tlen=len;
	for(uint8_t i=0;i<RECV_BUF_NUM;i++)
	{
		if(cdc_recv_len[i]==0)
		{
			if(tlen>RECV_BUF_SIZE)tlen=RECV_BUF_SIZE;
			memcpy(cdc_recv_buf[i],buf,tlen);
			cdc_recv_len[i]=tlen;
			return tlen;
		}
	}
	return 0;
}
uint32_t cuart_recv()
{
	uint16_t tlen=0;
	for(uint8_t i=0;i<RECV_BUF_NUM;i++)
	{
		if(cdc_recv_len[i]!=0)
		{
			tlen=cdc_recv_len[i];
			CDC_Transmit_FS(cdc_recv_buf[i],cdc_recv_len[i]);
			cdc_recv_len[i]=0;
			HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);
			return tlen;
		}	
	}
	return tlen;	
}


void cuart_iqr_handler()
{
	static uint8_t rbuf[128];
	static uint16_t rsize=0;
	if(__HAL_UART_GET_FLAG(cdcuart,UART_FLAG_RXNE)!=RESET)
	{
		__HAL_UART_CLEAR_FLAG(cdcuart,UART_FLAG_RXNE);
		rbuf[rsize++]=(uint8_t)(cdcuart->Instance->RDR & (uint8_t)0x00FF);
	}
	else if(__HAL_UART_GET_FLAG(cdcuart,UART_FLAG_IDLE)!=RESET)
	{ 
		__HAL_UART_CLEAR_FLAG(cdcuart,UART_FLAG_IDLE);		
		cuart_recv_store(rbuf,rsize);
		rsize=0;
	}
}
